package com.molihub.controller;

import com.molihub.entity.FileStore;
import com.molihub.entity.HomePage;
import com.molihub.entity.User;
import com.molihub.utils.LogUtils;
import com.molihub.utils.MailUtils;
import com.qq.connect.QQConnectException;
import com.qq.connect.api.OpenID;
import com.qq.connect.api.qzone.UserInfo;
import com.qq.connect.javabeans.AccessToken;
import com.qq.connect.javabeans.qzone.UserInfoBean;
import com.qq.connect.oauth.Oauth;
import org.slf4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @ClassName: LoginController
 * @Description: 登录控制器
 * @author: GGBOY xw
 * @date 2020/1/28 17:47
 * @Version: 1.0
 **/
@Controller
public class LoginController extends BaseController {

    private Logger logger = LogUtils.getInstance(UserController.class);


    @GetMapping("/admin")
    public String adminLogin(){
        User onlineUser = userService.getUserByUserNameAndPassword("admin", "admin");
        if (onlineUser != null){
            onlineUser.setStatus(1);
            userService.updateUserStatus(onlineUser);
            logger.info("登录成功！用户信息：" + onlineUser);
            session.setAttribute("loginUser", onlineUser);
            // 获得登录用户的好友列表
            List<User> friends = userFollowService.findAllFriendById(onlineUser.getUserId());
            session.setAttribute("friends", friends);
            logger.info("朋友列表: " + Arrays.toString(friends.toArray()));
        }
        return "redirect:/user-admin";
    }
    /**
     * 用于注册流程,用户名，密码，邮箱等校验工作由前端来完成
     *
     * @param map 用于存储提示信息
     * @author GGBOY
     * @date 2020/1/28
     */
    @PostMapping("/register")
    public String register(User user, String code, Map<String, Object> map) {
        String uCode = (String) session.getAttribute(user.getEmail() + "_code");
        if (!code.equals(uCode)) {
            map.put("errorMsg", "验证码错误~");
            return "login";
        }
        User exitUserName = userService.getUserByUserName(user.getUserName().trim());
        // 用户名去空格
        user.setUserName(user.getUserName().trim());
        if (exitUserName == null) {
            // 表示不存在同名用户并且邮箱没有被注册过,进行注册
            user.setImagePath("img/user/default.png");
            user.setRegisterTime(new Date());
            user.setBornDate(new Date());
            Integer result = userService.addUser(user);
            if (result == 1) {
                FileStore store = FileStore.builder().userId(user.getUserId()).currentSize(0).build();
                fileStoreService.addFileStore(store);
                user.setFileStoreId(store.getFileStoreId());
                userService.updateUser(user);
                logger.info("注册用户成功！当前注册用户" + user);
                logger.info("注册仓库成功！当前注册仓库" + store);
            } else {
                logger.error("注册失败");
            }

            session.removeAttribute(user.getEmail() + "_code");
            session.setAttribute("loginUser", user);
            // 同时在home_page表中添加一条对应该用户的个人主页记录
            HomePage homePage = new HomePage();
            homePage.setImagePath("img/choose-photo9.jpg");
            homePage.setUserId(user.getUserId());
            homePageService.addRecord(homePage);
            return "redirect:/index.html";
        } else {
            map.put("errorMsg", "呀！用户名被人使用啦~");
            return "login";
        }
    }

    /**
     * 用户登录
     *
     * @param map 存储提示信息
     * @return java.lang.String
     * @author GGBOY
     * @date 2020/1/28
     */
    @PostMapping("/login")
    public String login(User user, Map<String, Object> map) {
        User onlineUser = null;
        if (user.getUserName().contains("@")) {
            //邮箱登录
            User userByEmail = userService.getUserByEmail(user.getUserName());
            if (userByEmail != null && userByEmail.getPassword().equals(user.getPassword())) {
                onlineUser = userByEmail;
            }
        } else {
            //用户名登录
            onlineUser = userService.getUserByUserNameAndPassword(user.getUserName(), user.getPassword());
        }
        if (onlineUser == null) {
            logger.info("登录失败！请确认【用户名/邮箱】和密码是否正确！");
            // 用户不存在，提示用户是否用户名或密码错误
            map.put("errorMsg", "登录信息填写错误！");
            return "login";
        } else {
            onlineUser.setStatus(1);
            userService.updateUserStatus(onlineUser);
            logger.info("登录成功！用户信息：" + onlineUser);
            session.setAttribute("loginUser", onlineUser);
            // 获得登录用户的好友列表
            List<User> friends = userFollowService.findAllFriendById(onlineUser.getUserId());
            session.setAttribute("friends", friends);
            logger.info("朋友列表: " + Arrays.toString(friends.toArray()));
            return "redirect:/index.html";
        }
    }

    /**
     * @return void
     * @Description 向注册邮箱发送验证码, 并验证邮箱是否已使用
     * @Author xw
     * @Date 19:32 2020/1/29
     * @Param [userName, email, password]
     **/
    @ResponseBody
    @RequestMapping("/sendCode")
    public String sendCode(String userName, String email, String password) {
        User userByEmail = userService.getUserByEmail(email);
        if (userByEmail != null) {
            logger.error("发送验证码失败！邮箱已被注册！");
            return "exitEmail";
        }
        logger.info("开始发送邮件.../n" + "获取的到邮件发送对象为:" + mailSender);
        mailUtils = new MailUtils(mailSender);
        String code = mailUtils.sendCode(email, userName, password);
        session.setAttribute(email + "_code", code);
        return "success";
    }

    /**
     * 请求QQ登录
     */
    @RequestMapping("/loginByQQ")
    public void loginByQQ() {
        response.setContentType("text/html;charset=utf-8");
        try {
            response.sendRedirect(new Oauth().getAuthorizeURL(request));
            logger.info("请求QQ登录,开始跳转...");
        } catch (QQConnectException | IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * QQ登录回调地址
     *
     * @return
     */
    @RequestMapping("/connection")
    public String connection() {
        try {
            AccessToken accessTokenObj = (new Oauth()).getAccessTokenByRequest(request);
            String accessToken = null, openID = null;
            long tokenExpireIn = 0L;

            if ("".equals(accessTokenObj.getAccessToken())) {
                logger.error("登录失败:没有获取到响应参数");
                return "accessTokenObj=>" + accessTokenObj + "; accessToken" + accessTokenObj.getAccessToken();
            } else {
                accessToken = accessTokenObj.getAccessToken();
                tokenExpireIn = accessTokenObj.getExpireIn();
                logger.error("accessToken" + accessToken);
                request.getSession().setAttribute("demo_access_token", accessToken);
                request.getSession().setAttribute("demo_token_expirein", String.valueOf(tokenExpireIn));

                // 利用获取到的accessToken 去获取当前用的openid -------- start
                OpenID openIDObj = new OpenID(accessToken);
                openID = openIDObj.getUserOpenID();

                UserInfo qzoneUserInfo = new UserInfo(accessToken, openID);
                UserInfoBean userInfoBean = qzoneUserInfo.getUserInfo();
                if (userInfoBean.getRet() == 0) {

                    logger.info("用户的OPEN_ID: " + openID);
                    logger.info("用户的昵称: " + removeNonBmpUnicode(userInfoBean.getNickname()));
                    logger.info("用户的头像URI: " + userInfoBean.getAvatar().getAvatarURL100());
                    //设置用户信息
                    User user = userService.getUserByOpenId(openID);
                    if (user == null){
                        user = User.builder().openId(openID).build();
                        user.setUserName(removeNonBmpUnicode(userInfoBean.getNickname()));
                        user.setImagePath(userInfoBean.getAvatar().getAvatarURL100());
                        user.setRegisterTime(new Date());
                        user.setBornDate(new Date());
                        Integer result = userService.addUser(user);
                        if (result == 1) {
                            FileStore store = FileStore.builder().userId(user.getUserId()).currentSize(0).build();
                            fileStoreService.addFileStore(store);
                            user.setFileStoreId(store.getFileStoreId());
                            userService.updateUser(user);
                            logger.info("注册用户成功！当前注册用户" + user);
                            logger.info("注册仓库成功！当前注册仓库" + store);
                        } else {
                            logger.error("注册失败");
                        }
                    }
                    logger.info("QQ用户登录成功！"+user);
                    session.setAttribute("loginUser", user);
                    // 同时在home_page表中添加一条对应该用户的个人主页记录
                    HomePage homePage = new HomePage();
                    homePage.setImagePath("img/choose-photo9.jpg");
                    homePage.setUserId(user.getUserId());
                    homePageService.addRecord(homePage);
                    return "redirect:/index.html";
                } else {
                    logger.error("很抱歉，我们没能正确获取到您的信息，原因是： " + userInfoBean.getMsg());
                }
            }
        } catch (QQConnectException e) {
        } finally {
            logger.error("登录成功!");
        }
        return "登录失败!请查看日志信息...";
    }

    /**
     * 处理掉QQ网名中的特殊表情
     *
     * @param str
     * @return
     */
    public String removeNonBmpUnicode(String str) {
        if (str == null) {
            return null;
        }
        str = str.replaceAll("[^\\u0000-\\uFFFF]", "");
        if ("".equals(str)) {
            str = "($ _ $)";
        }
        return str;
    }

    /**
     * @return java.lang.String 返回到主页
     * @Description 退出登录，清空session
     * @Author xw
     * @Date 20:31 2020/1/29
     * @Param []
     **/
    @GetMapping("/logout")
    public String logout() {
        logger.info("用户退出登录！");
        loginUser.setStatus(0);
        userService.updateUserStatus(loginUser);
        List<User> friends = userFollowService.findAllFriendById(loginUser.getUserId());
        FriendController.notifyFriends(loginUser, friends);
        session.invalidate();
        return "redirect:/";
    }

}
